import { CipherGCM, createCipheriv, createDecipheriv, DecipherGCM, randomBytes, scryptSync } from 'crypto'

export class CryptoUtil {
  private static algorithm = 'aes-256-gcm' // 带认证的AES模式，防篡改
  private static secretKey: Buffer
  private static isInitialized = false

  // 初始化密钥（从环境变量读取）
  static init() {
    const key = '20230810tearslovecary20250207999'
    if (!key) throw new Error('未配置加密密钥')
    // 生成32字节密钥（AES-256要求）
    this.secretKey = scryptSync(key, 'nest-salt', 32)
    this.isInitialized = true
  }

  /**
   * 加密敏感数据
   * @param plaintext 明文（手机号/邮箱）
   * @returns 加密后字符串
   */
  static encrypt(plaintext: string): string {
    if (!this.isInitialized) {
      this.init()
    }
    if (!plaintext) return ''
    const iv = randomBytes(16) // 16字节随机向量（每次加密不同）
    const cipher = createCipheriv(this.algorithm, this.secretKey, iv) as CipherGCM
    const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()])
    const authTag = cipher.getAuthTag() // GCM模式的认证标签（防篡改）
    return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted.toString('hex')}`
  }

  /**
   * 解密敏感数据
   * @param ciphertext 加密字符串（iv:authTag:encryptedData）
   * @returns 明文
   */
  static decrypt(ciphertext: string): string {
    if (!this.isInitialized) {
      this.init()
    }
    if (!ciphertext) return ''
    const [ivHex, authTagHex, encryptedHex] = ciphertext.split(':')
    if (!ivHex || !authTagHex || !encryptedHex) {
      throw new Error('无效的加密格式')
    }
    const iv = Buffer.from(ivHex, 'hex')
    const authTag = Buffer.from(authTagHex, 'hex')
    const encrypted = Buffer.from(encryptedHex, 'hex')
    const decipher = createDecipheriv(this.algorithm, this.secretKey, iv) as DecipherGCM
    decipher.setAuthTag(authTag)
    return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString('utf8')
  }
}